#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 21-3-29 下午4:48
# @Author  : zgd
# @Site    : 
# @File    : views.py
# @Software: PyCharm
from flask import current_app
from flask import g
from flask import jsonify
from flask import redirect
from flask import render_template
from flask import request
from flask import session
import time

from info import constants, db
from info.models import User, News, Category
from info.utils.commons import user_login_data
from info.utils.image_storage import image_stroage
from info.utils.response_code import RET
from . import admin_blue, admin_blue
from datetime import datetime, timedelta


# 37.新闻分类添加/修改
# 请求路径: /admin/add_category
# 请求方式: POST
# 请求参数: id,name
# 返回值:errno,errmsg

@admin_blue.route('/add_category', methods=['POST'])
def add_category():

    #获取分类名称，ｉｄ
    category_id = request.json.get("id")
    category_name = request.json.get("name")

    if not  category_name:
        return jsonify(errno=RET.NODATA ,errmsg="分类不存在")

    # 有分类id，则是修改分类信息
    if category_id:
        try:
            #获取分类名称
            category = Category.query.get(category_id)
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno=RET.DBERR ,errmsg="获取分类失败")
        if not category:
            return jsonify(errno=RET.NODATA ,errmsg="该分类不存在")

        category.name = category_name

    # 新增分类数据
    else:
        # 创建分类对象，设置名称
        category = Category(name=category_name)
        try:
            db.session.add(category)
            db.session.commit()
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno=RET.DBERR ,errmsg="设置分类数据失败")

    return jsonify(errno=RET.OK ,errmsg="操作成功")



# 新闻分类管理
# 请求路径: /admin/news_category
# 请求方式: GET
# 请求参数: GET,无
# 返回值:GET,渲染news_type.html页面, data数据

@admin_blue.route('/news_category', methods=['GET', 'POST'])
def news_category():
    if request.method=="GET":
        try:
            categorys = Category.query.all()
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno=RET.DBERR ,errmsg="查询分类")

        return render_template("/admin/news_type.html",categorys = categorys)




# 请求路径: /admin/news_edit_detail
# 请求方式: GET, POST
# 请求参数: GET, news_id, POST(news_id,title,digest,content,index_image,category_id)
# 返回值:GET,渲染news_edit_detail.html页面,data字典数据, POST(errno,errmsg)

@admin_blue.route('/news_edit_detail', methods=['GET', 'POST'])
def news_edit_detail():
    if request.method == "GET":
        news_id = request.args.get("news_id")

            #携带新闻
        try:
            news = News.query.get(news_id)
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno=RET.DBERR, errmsg="查询新闻失败")
        if not news:
            return jsonify(errno=RET.DBERR ,errmsg="查询新闻不存在")

        # 携带分类
        try:
            categorys = Category.query.all()
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno=RET.DBERR ,errmsg="获取分类失败")
        # 分类对象列表数据转化成字典
        category_list = []
        for category in categorys:
            category_list.append(category)

        return render_template("admin/news_edit_detail.html",news = news.to_dict(),category_list=category_list)
    
    # 5.如果是POST请求,获取参数(news_id,title,digest,content,index_image,category_id)
    news_id = request.form.get("news_id")
    title = request.form.get("title")
    digest = request.form.get("digest")
    content = request.form.get("content")
    index_image = request.files.get("index_image")
    category_id = request.form.get("category_id")

    if not all([news_id,title,digest,content,index_image,category_id]):
        return jsonify(errno=RET.DATAERR ,errmsg="参数不全")

    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR ,errmsg="获取新闻失败")

    if not news:
        return jsonify(errno=RET.NODATA ,errmsg="新闻不存在")

    try:
        #读取图片,上传图片
        image_name = image_stroage(index_image.read())
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR ,errmsg="上传图片失败")

    if not image_name:
        return jsonify(errno=RET.NODATA ,errmsg="图片上传失败")

    #修改新闻的详细内容

    news.title = title
    news.digest = digest
    news.content = content
    news.index_image_url = constants.QINIU_DOMIN_PREFIX + image_name
    news.category_id = category_id

    return jsonify(errno=RET.OK ,errmsg="编辑成功")


# 请求路径: /admin/news_edit
# 请求方式: GET
# 请求参数: GET, p, keywords
# 返回值:GET,渲染news_edit.html页面,data字典数据
@admin_blue.route('/news_edit', methods=['GET', 'POST'])
def news_edit():
    page = request.args.get("p", "1")
    keywords = request.args.get("keywords", "")
    try:
        page = int(page)
    except:
        page = 1
    try:
        filters = []
        if keywords:
            filters.append(News.title.contains(keywords))
        paginate = News.query.filter(*filters).order_by(News.create_time.desc()).paginate(page, 5, False)
        # paginate = News.query.filter(*filters).order_by(News.create_time.desc()).paginate(page, 10, False)

    except Exception as e:
        current_app.logger.error(e)
        return render_template("admin/news_edit.html", errmsg="获取新闻失败")

    totalPage = paginate.pages
    currentPage = paginate.page
    items = paginate.items

    news_list = []
    for news in items:
        news_list.append(news.to_review_dict())

        data = {
            "totalPage": totalPage,
            "currentPage": currentPage,
            "news_list": news_list
        }
    return render_template("admin/news_edit.html", data=data)


@admin_blue.route('/news_review_detail', methods=['GET', 'POST'])
def news_review_detail():
    if request.method == "GET":
        news_id = request.args.get("news_id")
        try:
            news = News.query.get(news_id)
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno=RET.DBERR, errmsg="获取新闻失败")
        if not news:
            return jsonify(errno=RET.NODATA, errmsg="新闻不存在")
        return render_template("admin/news_review_detail.html", news=news.to_dict())

    action = request.json.get("action")
    news_id = request.json.get("news_id")

    if not all([action, news_id]):
        return jsonify(errno=RET.PARAMERR, errmsg="缺少参数数据")

    if not action in ["accept", "reject"]:
        return jsonify(errno=RET.DATAERR, errmsg="操作类型不正确")

    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="获取新闻失败")

    if not news:
        return jsonify(errno=RET.NODATA, errmsg="该新闻不存在")

    # 通过新闻的状态设置状态
    if action == "accept":
        news.status = 0
    else:
        news.status = -1
        news.reason == request.json.get("reason", "")
    return jsonify(errno=RET.OK, errmsg="操作成功")


# 请求路径: /admin/news_review
# 请求方式: GET
# 请求参数: GET, p,keyword
# 返回值:渲染user_list.html页面,data字典数据
@admin_blue.route('/news_review')
def news_review():
    """
      1. 获取参数,p
      2. 参数类型转换
      3. 分页查询用户数据
      4. 获取分页对象属性,总页数,当前页,当前页对象列表
      5. 将对象列表,转成字典列表
      6. 拼接数据,渲染页面
      :return:
      """
    # 1. 获取参数,p
    page = request.args.get("p", "1")
    keywords = request.args.get("keywords", "")

    # 2. 参数类型转换
    try:
        page = int(page)
    except Exception as e:
        page = 1

    # 3. 分页查询待审核,未通过的新闻数据
    try:

        # 3.1判断是否有填写搜索关键
        filters = [News.status != 0]
        if keywords:
            filters.append(News.title.contains(keywords))

        paginate = News.query.filter(*filters).order_by(News.create_time.desc()).paginate(page, 5, False)
    except Exception as e:
        current_app.logger.error(e)
        return render_template("admin/news_review.html", errmsg="获取新闻失败")

    # 4. 获取分页对象属性,总页数,当前页,当前页对象列表
    totalPage = paginate.pages
    currentPage = paginate.page
    items = paginate.items

    # 5. 将对象列表,转成字典列表
    news_list = []
    for news in items:
        news_list.append(news.to_review_dict())

    # 6. 拼接数据,渲染页面
    data = {
        "totalPage": totalPage,
        "currentPage": currentPage,
        "news_list": news_list
    }
    return render_template("admin/news_review.html", data=data)


# 用户列表页
# 请求路径: /admin/user_list
# 请求方式: GET
# 请求参数: p
# 返回值:渲染user_list.html页面,data字典数据
@admin_blue.route('/user_list')
def user_list():
    page = request.args.get("p")
    try:
        page = int(page)
    except:
        page = int(1)

    try:
        paginate = User.query.order_by(User.create_time.desc()).paginate(page, 15, False)
    except Exception as e:
        current_app.logger.error(e)
        return render_template("admin/user_list.html", errmsg="查询用户失败")

    totalPage = paginate.pages
    currentPage = paginate.page
    items = paginate.items

    user_list = []
    for user in items:
        user_list.append(user.to_admin_dict())

    data = {
        "totalPage": totalPage,
        "currentPage": currentPage,
        "user_list": user_list,
    }

    return render_template("admin/user_list.html", data=data)


# 用户统计图表页面
# 请求路径: /admin/user_count
# 请求方式: GET
# 请求参数: 无
# 返回值:渲染页面user_count.html,字典数据

@admin_blue.route('/user_count')
def user_count():
    # 统计总人数
    try:
        total_count = User.query.filter(User.is_admin == False).count()
    except Exception as e:
        current_app.logger.error(e)
        return render_template("/admin/user_count.html", errmsg="获取总人数失败")

    try:
        local_time = time.localtime()
        # 本月最后一次登陆的时间>= 本月１号０点人数

        # １．获取本月１号０点的字符串
        month_start_time_str = "%s-%s-01" % (local_time.tm_year, local_time.tm_mon)

        # ２．字符串　转化成日期对象
        month_start_time_data = datetime.strptime(month_start_time_str, "%Y-%m-%d")

        month_count = User.query.filter(User.last_login >= month_start_time_data, User.is_admin == False).count()

    except Exception as e:
        current_app.logger.error(e)
        return render_template("/admin/user_count.html", errmsg="获取月活人数失败")

    try:
        local_time = time.localtime()
        # 本日最后一次登陆的时间>= 本日　０点人数

        # １．获取本日０点的字符串
        day_start_time_str = "%s-%s-%s" % (local_time.tm_year, local_time.tm_mon, local_time.tm_mday)

        # ２．字符串　转化成日期对象
        day_start_time_data = datetime.strptime(day_start_time_str, "%Y-%m-%d")

        day_count = User.query.filter(User.last_login >= day_start_time_data, User.is_admin == False).count()

    except Exception as e:
        current_app.logger.error(e)
        return render_template("/admin/user_count.html", errmsg="获取月活人数失败")

    # active_date = []
    # active_count = []
    #
    # for i in range(0,7):
    #
    #     # 当天时间　　Ａ
    #     begin_date = day_start_time_data - timedelta(days=i)
    #
    #     #当天的后一天　Ｂ
    #     end_date = day_start_time_data-timedelta(days=i)
    #
    #
    #     active_date.append(begin_date.strftime("%Y-%m-%d"))
    #
    #     # 查询Ａ－Ｂ这一天的人数
    #     every_active_count = User.query.filter(User.is_admin==False,User.last_login>=begin_date,User.last_login<=end_date)
    #
    #     active_count.append(every_active_count)
    #
    # #容器翻转
    # active_count.reverse()
    # active_date.reverse()
    # 4.获取活跃时间段内,对应的活跃人数
    active_date = []  # 获取活跃的日期
    active_count = []  # 获取活跃的人数
    for i in range(0, 31):
        # 当天开始时间A
        begin_date = day_start_time_data - timedelta(days=i)
        # 当天开始时间, 的后⼀一天B 
        end_date = day_start_time_data - timedelta(days=i - 1)
        # 添加当天开始时间字符串串到, 活跃⽇日期中
        active_date.append(begin_date.strftime("%m-%d"))
        # 查询时间A到B这⼀一天的注册⼈人数
        everyday_active_count = User.query.filter(User.is_admin == False, User.last_login >= begin_date,
                                                  User.last_login <= end_date).count()
        # 添加当天注册⼈人数到,获取数量量中
        active_count.append(everyday_active_count)

    # 为了图表显示方便,将容器反转
    active_count.reverse()
    active_date.reverse()

    data = {
        "total_count": total_count,
        "month_count": month_count,
        "day_count": day_count,
        "active_date": active_date,
        "active_count": active_count

    }
    return render_template("admin/user_count.html", data=data)


# 请求路径: /admin/login
# 请求方式: GET,POST
# 请求参数:GET,无, POST,username,password
# 返回值: GET渲染login.html页面, POST,login.html页面,errmsg

@admin_blue.route('/index')
@user_login_data
def index():
    data = {
        "user_info": g.user.to_dict() if g.user else ""
    }

    return render_template("admin/index.html", data=data)


@admin_blue.route('/login', methods=["GET", "POST"])
def admin_login():
    """
    1.判断请求方式,如果是GET,直接渲染页面
    2.如果是POST请求,获取参数
    3.校验参数,为空校验
    4.根据用户名取出管理员对象,判断管理员是否存在
    5.判断管理员的密码是否正确
    6.管理的session信息记录
    7.重定向到首页展示
    :return:
    """
    # 1.判断请求方式,如果是GET,直接渲染页面
    if request.method == "GET":
        # 判断是否是admin登陆，如果是登陆过了，则跳转到首页
        if session.get("is_admin"):
            return redirect("/admin/index")

        return render_template("admin/login.html")

    # 2.    如果是POST请求, 获取参数
    username = request.form.get("username")
    password = request.form.get("password")

    # 3.  校验参数, 为空校验
    if not all([username, password]):
        return render_template("admin/login.html", errmsg="参数不全")

    # 4.根据用户名取出管理员对象,判断管理员是否存在
    try:
        admin = User.query.filter(User.mobile == username, User.is_admin == True).first()
    except Exception as e:
        current_app.logger.error(e)
        return render_template("admin/login.html", errmsg="查询用户失败")
    if not admin:
        return render_template("admin/login.html", errmsg="管理员不存在")

    # 5.判断管理员的密码是否正确
    if not admin.check_password(password):
        return render_template("admin/login.html", errmsg="密码不正确")

    # 6.管理的session信息记录
    session["user_id"] = admin.id
    session["is_admin"] = True

    return redirect("/admin/index")
